package com.xuecheng.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.xuecheng.common.domain.code.CommonErrorCode;
import com.xuecheng.common.enums.common.CommonEnum;
import com.xuecheng.common.enums.order.OrderDealStatusEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.StringUtil;
import com.xuecheng.order.common.constant.OrderErrorCode;
import com.xuecheng.order.entity.Orders;
import com.xuecheng.order.entity.Pay;
import com.xuecheng.order.mapper.PayMapper;
import com.xuecheng.order.service.OrdersService;
import com.xuecheng.order.service.PayService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 订单支付信息 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class PayServiceImpl extends ServiceImpl<PayMapper, Pay> implements PayService {

    @Autowired
    private OrdersService ordersService;

    @Autowired
    private WxPayService wxPayService;
    /**
     * 1.判断关键数据
     * orderNo  userName
     * 2.根据数据获得订单数据并进行判断
     * 判断订单数据是否存在
     * 判断订单状态(只有未支付的订单才能生成订单支付信息)
     * 3.调用微信api进行统一下单
     * 获得code_url
     * 4.生成订单支付信息
     * 先查询订单数据是否有订单支付信息
     * 5.返回codeURL(二维码链接)
     */
    @Transactional
    public Map<String, Object> createPay(String orderNo, String userName) {
        //1.判断关键数据
        if (StringUtil.isEmpty(orderNo) || StringUtil.isEmpty(userName)) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        //2.根据数据获得订单数据并进行判断
        LambdaQueryWrapper<Orders> ordersQueryWrapper = new LambdaQueryWrapper<>();
        ordersQueryWrapper.eq(Orders::getOrderNo, orderNo);
        ordersQueryWrapper.eq(Orders::getUserName, userName);

        Orders orders = ordersService.getOne(ordersQueryWrapper);
        //判断订单数据是否存在
        if (ObjectUtils.isEmpty(orders)) {
            ExceptionCast.cast(OrderErrorCode.E_160008);
        }
        //判断订单状态(只有未支付的订单才能生成订单支付信息)
        if (!(OrderDealStatusEnum.ORDER_DEAL_INIT_STATUS.getCode().equals(orders.getStatus().toString()))) {
            ExceptionCast.cast(OrderErrorCode.E_160006);
        }

        //3.调用微信api进行统一下单
        //获得code_url
        Map<String,Object> resultMap = getResultMap(orderNo, orders);

        //4.生成订单支付信息
        //先查询订单数据是否有订单支付信息
        LambdaQueryWrapper<Pay> payQueryWrapper = new LambdaQueryWrapper<>();
        payQueryWrapper.eq(Pay::getOrderId, orders.getId());
        payQueryWrapper.eq(Pay::getUserName, userName);

        Pay pay = this.getOne(payQueryWrapper);
        if (ObjectUtils.isEmpty(pay)) {
            //创建订单支付信息
            pay = new Pay();
            //主键
            pay.setId(null);
            pay.setUserName(userName);
            pay.setCompanyId(orders.getCompanyId());
            pay.setOrderId(orders.getId());
            pay.setStatus(Pay.IS_NOT_PAY);
            pay.setPayMethod(Pay.PAY_METHOD_WX);
            pay.setTotalAmount(new BigDecimal(orders.getPrice()));

            boolean save = this.save(pay);
            if (!save) {
                ExceptionCast.cast(OrderErrorCode.E_160009);
            }
        }

        //5.返回codeURL(二维码链接)
        return resultMap;
    }

    private Map<String,Object> getResultMap(String orderNo, Orders orders) {

        HashMap<String, Object> resultMap = new HashMap<>();

        try {
            //3.调用微信api进行统一下单
            //创建统一下单请求对象
            WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
            //设置统一下单数据
            //商品描述
            request.setBody(orders.getCoursePubName());
            //订单号
            // PS:一定要和Order中的orderNo 一致，如果不一致，后期支付成功的回调方法将无法找到对应的orders数据
            request.setOutTradeNo(orderNo);
            //金额 单位:分
            Float price = orders.getPrice() * 100;
            request.setTotalFee(price.intValue());
            //终端ip
            request.setSpbillCreateIp(InetAddress.getLocalHost().getHostAddress());
            //商品id
            request.setProductId(orders.getCoursePubId().toString());
            //获得统一下单结果数据
            WxPayUnifiedOrderResult response = wxPayService.unifiedOrder(request);

            //获得二维码url地址
            String resultCode = response.getResultCode();
            String returnCode = response.getReturnCode();

            if (Pay.WX_PAY_RESPONSE_SUCCESS.equals(resultCode) && Pay.WX_PAY_RESPONSE_SUCCESS.equals(returnCode)) {
                String codeURL = response.getCodeURL();

                // 获得成功支付数据
                resultMap.put("status", CommonEnum.USING_FLAG.getCode());
                resultMap.put("codeURL", codeURL);
            } else {
                // 获得失败支付数据
                resultMap.put("status", CommonEnum.DELETE_FLAG);
                resultMap.put("message", OrderErrorCode.E_160014.getDesc());
            }
        } catch (Exception e) {
            log.error("获得微信二维码url地址失败: {}", e.getMessage());
            resultMap.put("status", CommonEnum.DELETE_FLAG);
            resultMap.put("message", OrderErrorCode.E_160014.getDesc());
        }
        return resultMap;
    }
}
